require(Matrix)
require(tseries)
#source("http://lu-library.googlecode.com/svn/trunk/classification.r")


MaskLabel <- function(labelfile, partationfile, labeltomask) {
	d = as.vector(read.table(labelfile))
	part = read.table(partationfile)
	labs <- list()
	classes <- c()
	for(i in 1:nrow(d)) {
		labs[[i]] = unassemble(as.character(d[i,2]))
		classes = union(classes, labs[[i]])
	}
	
	classes = sort(unique(classes))
	
	bin_matrix <- matrix(0, nrow = nrow(d), ncol = length(classes))
	for(i in 1:nrow(d)) {
		for(j in labs[[i]]) {
			bin_matrix[i,j]=1
		}
	}
	#bin_matrix[,labelmask]
	lcol = bin_matrix[,labeltomask]
	
	
	#label 1 positive and 2 negative
	lcol[which(lcol==0)] = 2
	result = d
	result[,2] = lcol
	write(t(result), file = paste("new_bin_label",".label",sep=""), ncol = 2)
}


RandomSplit <- function(classids, idlist, bin_matrix, ncopy = 10, multilabel.balance=FALSE) {
	#Randomly 50% divde the dataset into training and test set.
	#	example: RandomSplit(1:366, myidlist, bin_matrix,10)
	#classids: the numeric range of classes (label staring from 1)
	#idlist: vector of ids
	#bin_matrix: label matrix represented in binary
	#ncopy: how many partition file to output
	#multilabel.balance: for a multiclass classification whether ensure each class has at least 50% training data
	if(multilabel.balance) {
		for(i in 1:ncopy) {
			result =  replicate(nrow(bin_matrix),-1)
			#sample each class
			for(j in classids) {
				population = which(bin_matrix[,j]==1)
				samplesize = ceiling(length(population)/2)
				population = intersect(population,which(result!=0))
				trids <- population[sample(1:length(population), min(samplesize,length(population)))]
				tsids <- setdiff(population,trids)
				result[trids] = 0
				result[tsids] = 1
			}
			partation = cbind(idlist, result)
			write(t(partation), file = paste("partition",i,".par",sep=""), ncol = 2)
		}
	} else {
		for(i in 1:ncopy) {
			result =  replicate(nrow(bin_matrix),-1)
			#sample each class
			for(j in classids) {
				population = which(bin_matrix[,j]==1)
				trids <- population[sample(1:length(population), ceiling(length(population)*0.5))]
				tsids <- setdiff(population,trids)
				result[trids] = 0
				result[tsids] = 1
			}
			partation = cbind(idlist, result)
			write(t(partation), file = paste("partition",i,".par",sep=""), ncol = 2)
		}
	}
}


ConvnetTrTsList <- function(labelfile, partitionfile, outdir = ".") {
	#Generate the input files for cuda-convnet: called "training.list" and "testing.list"
	#	example: ConvnetTrTsList("mylabels", "mypartition")
	#labelfile: two column file with the format: ID label
	#partitionfile: two column file with the format: ID [0,1] (0 for training and 1 for testing)
	
	labels = read.table(labelfile)
	partition = read.table(partitionfile)
	l = as.numeric(labels[,2])
	if(length(which((partition[,1]==labels[,1])==FALSE))>0)	{
		print("partition and label files have different ID column")
		return()
	}
	if(min(l) != 1)	{
		print("labels must be staring from 1")
		return()
	}
	#else if(length(unique(l)) != max(l)) {
	#	print("labels must be consecutive")
	#	return()
	#}
	
	p = as.numeric(partition[,2])
	
	trainingidx = which(p==0)
	testidx = which(p==1)
	
	#shuffle the samples before the output
	write.table(labels[sample(trainingidx),], quote=FALSE, file = file.path(outdir,"training.list"), row.names=FALSE, col.names=FALSE)
	write.table(labels[sample(testidx),], quote=FALSE, file = file.path(outdir,"test.list"), row.names=FALSE, col.names=FALSE)
}


PrintFileStatistics <- function(infile) {
	#Print the statistics of the infile: #samples, #samples each class
	#infile: "labels.labels", "training.list" or "test.list"
	tab = read.table(infile)
	classes = sort(unique(tab[,2]))
	sizes = replicate(length(classes),0)
	for(i in sort(unique(tab[,2]))) {
		sizes[i] = length(which(tab[,2]==i))
	}
	
	print(paste("min per class:", min(sizes)))
	print(paste("max per class:", max(sizes)))
	print(paste("mean per class:", mean(sizes)))
	print(paste("median per class:", median(sizes)))
}



unassemble <- function(str.label) {
	return(as.numeric(strsplit(str.label,",")[[1]]))
}
